home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 022 / lemacs / word.c < prev   
C/C++ Source or Header  |  1995-03-17  |  13KB  |  432 lines

  1. /*
  2.  * The routines in this file implement commands that work word at a time.
  3.  * There are all sorts of word mode commands. If I do any sentence and/or
  4.  * paragraph mode commands, they are likely to be put in this file.
  5.  */
  6.  
  7. #include        <stdio.h>
  8. #include        "estruct.h"
  9. #include    "edef.h"
  10.  
  11. /* Word wrap on n-spaces. Back-over whatever precedes the point on the current
  12.  * line and stop on the first word-break or the beginning of the line. If we
  13.  * reach the beginning of the line, jump back to the end of the word and start
  14.  * a new line.  Otherwise, break the line at the word-break, eat it, and jump
  15.  * back to the end of the word.
  16.  * Returns TRUE on success, FALSE on errors.
  17.  */
  18. wrapword(n)
  19. int n;
  20. {
  21.         register int cnt;    /* size of word wrapped to next line */
  22.  
  23.     /* backup from the <NL> 1 char */
  24.         if (!backchar(0, 1))
  25.             return(FALSE);
  26.  
  27.     /* back up until we aren't in a word,
  28.        make sure there is a break in the line */
  29.         cnt = 0;
  30.         while (inword()) {
  31.                 cnt++;
  32.                 if (!backchar(0, 1))
  33.                         return(FALSE);
  34.         }
  35.  
  36.     /* delete the forward space */
  37.         if (!forwdel(0, 1))
  38.                 return(FALSE);
  39.  
  40.     /* put in a end of line */
  41.         if (!newline(0, 1))
  42.                 return(FALSE);
  43.  
  44.     /* and past the first word */
  45.     while (cnt-- > 0) {
  46.         if (forwchar(FALSE, 1) == FALSE)
  47.             return(FALSE);
  48.     }
  49.         return(TRUE);
  50. }
  51.  
  52. /*
  53.  * Move the cursor backward by "n" words. All of the details of motion are
  54.  * performed by the "backchar" and "forwchar" routines. Error if you try to
  55.  * move beyond the buffers.
  56.  */
  57. backword(f, n)
  58. {
  59.         if (n < 0)
  60.                 return (forwword(f, -n));
  61.         if (backchar(FALSE, 1) == FALSE)
  62.                 return (FALSE);
  63.         while (n--) {
  64.                 while (inword() == FALSE) {
  65.                         if (backchar(FALSE, 1) == FALSE)
  66.                                 return (FALSE);
  67.                 }
  68.                 while (inword() != FALSE) {
  69.                         if (backchar(FALSE, 1) == FALSE)
  70.                                 return (FALSE);
  71.                 }
  72.         }
  73.         return (forwchar(FALSE, 1));
  74. }
  75.  
  76. /*
  77.  * Move the cursor forward by the specified number of words. All of the motion
  78.  * is done by "forwchar". Error if you try and move beyond the buffer's end.
  79.  */
  80. forwword(f, n)
  81. {
  82.         if (n < 0)
  83.                 return (backword(f, -n));
  84.         while (n--) {
  85. #if    NFWORD
  86.                 while (inword() != FALSE) {
  87.                         if (forwchar(FALSE, 1) == FALSE)
  88.                                 return (FALSE);
  89.                 }
  90. #endif
  91.                 while (inword() == FALSE) {
  92.                         if (forwchar(FALSE, 1) == FALSE)
  93.                                 return (FALSE);
  94.                 }
  95. #if    NFWORD == 0
  96.                 while (inword() != FALSE) {
  97.                         if (forwchar(FALSE, 1) == FALSE)
  98.                                 return (FALSE);
  99.                 }
  100. #endif
  101.         }
  102.     return(TRUE);
  103. }
  104.  
  105. /*
  106.  * Move the cursor forward by the specified number of words. As you move,
  107.  * convert any characters to upper case. Error if you try and move beyond the
  108.  * end of the buffer. Bound to "M-U".
  109.  */
  110. upperword(f, n)
  111. {
  112.         register int    c;
  113.  
  114.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  115.         return(rdonly());    /* we are in read only mode    */
  116.         if (n < 0)
  117.                 return (FALSE);
  118.         while (n--) {
  119.                 while (inword() == FALSE) {
  120.                         if (forwchar(FALSE, 1) == FALSE)
  121.                                 return (FALSE);
  122.                 }
  123.                 while (inword() != FALSE) {
  124.                         c = lgetc(curwp->w_dotp, curwp->w_doto);
  125.                         if (c>='a' && c<='z') {
  126.                                 c -= 'a'-'A';
  127.                                 lputc(curwp->w_dotp, curwp->w_doto, c);
  128.                                 lchange(WFHARD);
  129.                         }
  130.                         if (forwchar(FALSE, 1) == FALSE)
  131.                                 return (FALSE);
  132.                 }
  133.         }
  134.         return (TRUE);
  135. }
  136.  
  137. /*
  138.  * Move the cursor forward by the specified number of words. As you move
  139.  * convert characters to lower case. Error if you try and move over the end of
  140.  * the buffer. Bound to "M-L".
  141.  */
  142. lowerword(f, n)
  143. {
  144.         register int    c;
  145.  
  146.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  147.         return(rdonly());    /* we are in read only mode    */
  148.         if (n < 0)
  149.                 return (FALSE);
  150.         while (n--) {
  151.                 while (inword() == FALSE) {
  152.                         if (forwchar(FALSE, 1) == FALSE)
  153.                                 return (FALSE);
  154.                 }
  155.                 while (inword() != FALSE) {
  156.                         c = lgetc(curwp->w_dotp, curwp->w_doto);
  157.                         if (c>='A' && c<='Z') {
  158.                                 c += 'a'-'A';
  159.                                 lputc(curwp->w_dotp, curwp->w_doto, c);
  160.                                 lchange(WFHARD);
  161.                         }
  162.                         if (forwchar(FALSE, 1) == FALSE)
  163.                                 return (FALSE);
  164.                 }
  165.         }
  166.         return (TRUE);
  167. }
  168.  
  169. /*
  170.  * Move the cursor forward by the specified number of words. As you move
  171.  * convert the first character of the word to upper case, and subsequent
  172.  * characters to lower case. Error if you try and move past the end of the
  173.  * buffer. Bound to "M-C".
  174.  */
  175. capword(f, n)
  176. {
  177.         register int    c;
  178.  
  179.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  180.         return(rdonly());    /* we are in read only mode    */
  181.         if (n < 0)
  182.                 return (FALSE);
  183.         while (n--) {
  184.                 while (inword() == FALSE) {
  185.                         if (forwchar(FALSE, 1) == FALSE)
  186.                                 return (FALSE);
  187.                 }
  188.                 if (inword() != FALSE) {
  189.                         c = lgetc(curwp->w_dotp, curwp->w_doto);
  190.                         if (c>='a' && c<='z') {
  191.                                 c -= 'a'-'A';
  192.                                 lputc(curwp->w_dotp, curwp->w_doto, c);
  193.                                 lchange(WFHARD);
  194.                         }
  195.                         if (forwchar(FALSE, 1) == FALSE)
  196.                                 return (FALSE);
  197.                         while (inword() != FALSE) {
  198.                                 c = lgetc(curwp->w_dotp, curwp->w_doto);
  199.                                 if (c>='A' && c<='Z') {
  200.                                         c += 'a'-'A';
  201.                                         lputc(curwp->w_dotp, curwp->w_doto, c);
  202.                                         lchange(WFHARD);
  203.                                 }
  204.                                 if (forwchar(FALSE, 1) == FALSE)
  205.                                         return (FALSE);
  206.                         }
  207.                 }
  208.         }
  209.         return (TRUE);
  210. }
  211.  
  212. /*
  213.  * Kill forward by "n" words. Remember the location of dot. Move forward by
  214.  * the right number of words. Put dot back where it was and issue the kill
  215.  * command for the right number of characters. Bound to "M-D".
  216.  */
  217. delfword(f, n)
  218. {
  219.         register int    size;
  220.         register LINE   *dotp;
  221.         register int    doto;
  222.  
  223.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  224.         return(rdonly());    /* we are in read only mode    */
  225.         if (n < 0)
  226.                 return (FALSE);
  227.         dotp = curwp->w_dotp;
  228.         doto = curwp->w_doto;
  229.         size = 0;
  230.         while (n--) {
  231. #if    NFWORD
  232.         while (inword() != FALSE) {
  233.             if (forwchar(FALSE,1) == FALSE)
  234.                 return(FALSE);
  235.             ++size;
  236.         }
  237. #endif
  238.                 while (inword() == FALSE) {
  239.                         if (forwchar(FALSE, 1) == FALSE)
  240.                                 return (FALSE);
  241.                         ++size;
  242.                 }
  243. #if    NFWORD == 0
  244.                 while (inword() != FALSE) {
  245.                         if (forwchar(FALSE, 1) == FALSE)
  246.                                 return (FALSE);
  247.                         ++size;
  248.                 }
  249. #endif
  250.         }
  251.         curwp->w_dotp = dotp;
  252.         curwp->w_doto = doto;
  253.         return (ldelete(size, TRUE));
  254. }
  255.  
  256. /*
  257.  * Kill backwards by "n" words. Move backwards by the desired number of words,
  258.  * counting the characters. When dot is finally moved to its resting place,
  259.  * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
  260.  */
  261. delbword(f, n)
  262. {
  263.         register int    size;
  264.  
  265.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  266.         return(rdonly());    /* we are in read only mode    */
  267.         if (n < 0)
  268.                 return (FALSE);
  269.         if (backchar(FALSE, 1) == FALSE)
  270.                 return (FALSE);
  271.         size = 0;
  272.         while (n--) {
  273.                 while (inword() == FALSE) {
  274.                         if (backchar(FALSE, 1) == FALSE)
  275.                                 return (FALSE);
  276.                         ++size;
  277.                 }
  278.                 while (inword() != FALSE) {
  279.                         if (backchar(FALSE, 1) == FALSE)
  280.                                 return (FALSE);
  281.                         ++size;
  282.                 }
  283.         }
  284.         if (forwchar(FALSE, 1) == FALSE)
  285.                 return (FALSE);
  286.         return (ldelete(size, TRUE));
  287. }
  288.  
  289. /*
  290.  * Return TRUE if the character at dot is a character that is considered to be
  291.  * part of a word. The word character list is hard coded. Should be setable.
  292.  */
  293. inword()
  294. {
  295.         register int    c;
  296.  
  297.         if (curwp->w_doto == llength(curwp->w_dotp))
  298.                 return (FALSE);
  299.         c = lgetc(curwp->w_dotp, curwp->w_doto);
  300.         if (c>='a' && c<='z')
  301.                 return (TRUE);
  302.         if (c>='A' && c<='Z')
  303.                 return (TRUE);
  304.         if (c>='0' && c<='9')
  305.                 return (TRUE);
  306.         if (c=='$' || c=='_')                   /* For identifiers      */
  307.                 return (TRUE);
  308.         return (FALSE);
  309. }
  310.  
  311. fillpara(f, n)    /* Fill the current paragraph according to the current
  312.            fill column                        */
  313.  
  314. int f, n;    /* deFault flag and Numeric argument */
  315.  
  316. {
  317.     register int c;            /* current char durring scan    */
  318.     register int wordlen;        /* length of current word    */
  319.     register int clength;        /* position on line during fill    */
  320.     register int i;            /* index during word copy    */
  321.     register int newlength;        /* tentative new line length    */
  322.     register int eopflag;        /* Are we at the End-Of-Paragraph? */
  323.     register int firstflag;        /* first word? (needs no space)    */
  324.     register LINE *eopline;        /* pointer to line just past EOP */
  325.     register int dotflag;        /* was the last char a period?    */
  326.     char wbuf[NSTRING];        /* buffer for current word    */
  327.  
  328.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  329.         return(rdonly());    /* we are in read only mode    */
  330.     if (fillcol == 0) {    /* no fill column set */
  331.         mlwrite("No fill column set");
  332.         return(FALSE);
  333.     }
  334.  
  335.     /* record the pointer to the line just past the EOP */
  336.     gotoeop(FALSE, 1);
  337.     eopline = lforw(curwp->w_dotp);
  338.  
  339.     /* and back top the begining of the paragraph */
  340.     gotobop(FALSE, 1);
  341.  
  342.     /* initialize various info */
  343.     clength = curwp->w_doto;
  344.     if (clength && curwp->w_dotp->l_text[0] == TAB)
  345.         clength = 8;
  346.     wordlen = 0;
  347.     dotflag = FALSE;
  348.  
  349.     /* scan through lines, filling words */
  350.     firstflag = TRUE;
  351.     eopflag = FALSE;
  352.     while (!eopflag) {
  353.         /* get the next character in the paragraph */
  354.         if (curwp->w_doto == llength(curwp->w_dotp)) {
  355.             c = ' ';
  356.             if (lforw(curwp->w_dotp) == eopline)
  357.                 eopflag = TRUE;
  358.         } else
  359.             c = lgetc(curwp->w_dotp, curwp->w_doto);
  360.  
  361.         /* and then delete it */
  362.         ldelete(1, FALSE);
  363.  
  364.         /* if not a separator, just add it in */
  365.         if (c != ' ' && c != '    ') {
  366.             dotflag = (c == '.');        /* was it a dot */
  367.             if (wordlen < NSTRING - 1)
  368.                 wbuf[wordlen++] = c;
  369.         } else if (wordlen) {
  370.             /* at a word break with a word waiting */
  371.             /* calculate tantitive new length with word added */
  372.             newlength = clength + 1 + wordlen;
  373.             if (newlength <= fillcol) {
  374.                 /* add word to current line */
  375.                 if (!firstflag) {
  376.                     linsert(1, ' '); /* the space */
  377.                     ++clength;
  378.                 }
  379.                 firstflag = FALSE;
  380.             } else {
  381.                 /* start a new line */
  382.                 lnewline();
  383.                 clength = 0;
  384.             }
  385.  
  386.             /* and add the word in in either case */
  387.             for (i=0; i<wordlen; i++) {
  388.                 linsert(1, wbuf[i]);
  389.                 ++clength;
  390.             }
  391.             if (dotflag) {
  392.                 linsert(1, ' ');
  393.                 ++clength;
  394.             }
  395.             wordlen = 0;
  396.         }
  397.     }
  398.     /* and add a last newline for the end of our new paragraph */
  399.     lnewline();
  400. }
  401.  
  402. killpara(f, n)    /* delete n paragraphs starting with the current one */
  403.  
  404. int f;    /* default flag */
  405. int n;    /* # of paras to delete */
  406.  
  407. {
  408.     register int status;    /* returned status of functions */
  409.  
  410.     while (n--) {        /* for each paragraph to delete */
  411.  
  412.         /* mark out the end and begining of the para to delete */
  413.         gotoeop(FALSE, 1);
  414.  
  415.         /* set the mark here */
  416.             curwp->w_markp = curwp->w_dotp;
  417.             curwp->w_marko = curwp->w_doto;
  418.  
  419.         /* go to the begining of the paragraph */
  420.         gotobop(FALSE, 1);
  421.         curwp->w_doto = 0;    /* force us to the begining of line */
  422.     
  423.         /* and delete it */
  424.         if ((status = killregion(FALSE, 1)) != TRUE)
  425.             return(status);
  426.  
  427.         /* and clean up the 2 extra lines */
  428.         ldelete(2, TRUE);
  429.     }
  430.     return(TRUE);
  431. }
  432.